package me.zxk.qwert_poetry.util;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import me.zxk.qwert_poetry.dao.User;
import me.zxk.qwert_poetry.dto.response.Response;
import me.zxk.qwert_poetry.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.IOException;
import java.lang.reflect.Method;

@Component
public class TokenInterceptor implements HandlerInterceptor {
    @Autowired
    private UserService userService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 过滤非 API 请求
        String uri = request.getRequestURI();
        if (!uri.startsWith("/api"))
            return true;
        
        // 过滤不需要鉴权的 API
        boolean needToken = false;
        VerifyToken verifyToken = null;
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();

            if (method.isAnnotationPresent(VerifyToken.class)) {
                needToken = true;
                verifyToken = method.getAnnotation(VerifyToken.class);
            } else if (method.getDeclaringClass().isAnnotationPresent(VerifyToken.class)) {
                needToken = true;
                verifyToken = method.getDeclaringClass().getAnnotation(VerifyToken.class);
            }
            if (needToken && verifyToken == null)
                throw new RuntimeException("VerifyToken annotation not found.");

        }

        // 验证 Token

        String rawToken = request.getHeader("Authorization");
        if (StringUtil.isNullOrEmpty(rawToken))
            return !needToken || unauthorized(response);

        String token = rawToken.substring("Bearer ".length());
        Integer id = JwtUtil.parseJwtToken(token);
        if (id == null)
            return !needToken || unauthorized(response);
        User u = userService.getUserById(id);
        if (u == null)
            return !needToken || unauthorized(response);

        if (verifyToken != null && verifyToken.needAdmin() && !u.getRole().equals(User.ROLE_ADMIN))
            return forbidden(response);

        UserContextHolder.setUserContext(new UserContext(u));
        return true;

    }

    private boolean unauthorized(HttpServletResponse response) throws IOException {
        response.setContentType("application/json");
        response.getWriter().write(new Response<Void>("Unauthorized", 401).toString());
        return false;
    }

    private boolean forbidden(HttpServletResponse response) throws IOException {
        response.setContentType("application/json");
        response.getWriter().write(new Response<Void>("Forbidden", 403).toString());
        return false;
    }

}
